home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / x+opengl / glxmotif.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  6KB  |  211 lines

  1. /* $Revision: 1.1 $ */
  2. /* compile: cc -o glxmotif glxmotif.c -lGLU -lGL -lXm -lXt -lX11 */
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <Xm/Form.h>
  6. #include <Xm/Frame.h>
  7. #include <Xm/DrawingA.h>
  8. #include <X11/keysym.h>
  9. #include <GL/gl.h>
  10. #include <GL/glu.h>
  11. #include <GL/glx.h>
  12.  
  13. static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
  14. static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
  15. static String   fallbackResources[] = {
  16.     "*glxarea*width: 300", "*glxarea*height: 300",
  17.     "*frame*x: 20", "*frame*y: 20",
  18.     "*frame*topOffset: 20", "*frame*bottomOffset: 20",
  19.     "*frame*rightOffset: 20", "*frame*leftOffset: 20",
  20.     "*frame*shadowType: SHADOW_IN",
  21.     NULL
  22. };
  23.  
  24. Display        *dpy;
  25. GLboolean       doubleBuffer = GL_TRUE, viewportUpdateNeeded = GL_TRUE, spinning = GL_FALSE;
  26. XtAppContext    app;
  27. XtWorkProcId    workId = 0;
  28. Widget          toplevel, form, frame, glxarea;
  29.  
  30. void
  31. updateViewport(Widget w)
  32. {
  33.     Dimension width, height;
  34.  
  35.     XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
  36.     glViewport(0, 0, (GLint) width, (GLint) height);
  37.     viewportUpdateNeeded = GL_FALSE;
  38. }
  39.  
  40. void
  41. draw(Widget w)
  42. {
  43.     if (viewportUpdateNeeded) updateViewport(w);
  44.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  45.     glBegin(GL_POLYGON);
  46.     glColor3f(0.0, 0.0, 0.0); glVertex3f(-10.0, -10.0, 0.0);
  47.     glColor3f(0.7, 0.7, 0.7); glVertex3f(10.0, -10.0, 0.0);
  48.     glColor3f(1.0, 1.0, 1.0); glVertex3f(-10.0, 10.0, 0.0);
  49.     glEnd();
  50.     glBegin(GL_POLYGON);
  51.     glColor3f(1.0, 1.0, 0.0); glVertex3f(0.0, -10.0, -10.0);
  52.     glColor3f(0.0, 1.0, 0.7); glVertex3f(0.0, -10.0, 10.0);
  53.     glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 5.0, -10.0);
  54.     glEnd();
  55.     glBegin(GL_POLYGON);
  56.     glColor3f(1.0, 1.0, 0.0); glVertex3f(-10.0, 6.0, 4.0);
  57.     glColor3f(1.0, 0.0, 1.0); glVertex3f(-10.0, 3.0, 4.0);
  58.     glColor3f(0.0, 0.0, 1.0); glVertex3f(4.0, -9.0, -10.0);
  59.     glColor3f(1.0, 0.0, 1.0); glVertex3f(4.0, -6.0, -10.0);
  60.     glEnd();
  61.     if (doubleBuffer) glXSwapBuffers(dpy, XtWindow(w));
  62.     glFlush();
  63. }
  64.  
  65. void
  66. expose(Widget w, XtPointer clientData, XtPointer callData)
  67. {
  68.     draw(w);
  69. }
  70.  
  71. void
  72. resize(Widget w, XtPointer clientData, XtPointer callData)
  73. {
  74.     XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
  75.  
  76.     /* don't try OpenGL until window is realized! */
  77.     if (XtIsRealized(w)) updateViewport(w);
  78.         else viewportUpdateNeeded = GL_TRUE;
  79. }
  80.  
  81. Boolean
  82. spin(XtPointer clientData)
  83. {
  84.     glRotatef(2.5, 1.0, 0.0, 0.0);
  85.     draw(glxarea);
  86.     return False; /* leave work proc active */
  87. }
  88.  
  89. void
  90. input(Widget w, XtPointer clientData, XtPointer callData)
  91. {
  92.     XmDrawingAreaCallbackStruct *cd = (XmDrawingAreaCallbackStruct *) callData;
  93.     char            buffer[1];
  94.     KeySym          keysym;
  95.     int             rc;
  96.  
  97.     switch (cd->event->type) {
  98.     case KeyRelease:
  99.     /*
  100.      * It is necessary to convert the keycode to a keysym before it is
  101.      * possible to check if it is an escape
  102.      */
  103.     rc = XLookupString((XKeyEvent *) cd->event, buffer, 1, &keysym, NULL);
  104.     switch (keysym) {
  105.     case XK_Up:
  106.         glRotatef(10.0, 0.0, 0.0, 1.0);
  107.         if (!spinning) draw(w);
  108.         break;
  109.     case XK_Down:
  110.         glRotatef(-10.0, 0.0, 0.0, 1.0);
  111.         if (!spinning) draw(w);
  112.         break;
  113.     case XK_Left:
  114.         glRotatef(-10.0, 0.0, 1.0, 0.0);
  115.         if (!spinning) draw(w);
  116.         break;
  117.     case XK_Right:
  118.         glRotatef(10.0, 0.0, 1.0, 0.0);
  119.         if (!spinning) draw(w);
  120.         break;
  121.     case XK_S: case XK_s: /* the S key */
  122.         if (spinning) {
  123.         XtRemoveWorkProc(workId);
  124.         spinning = GL_FALSE;
  125.         } else {
  126.         workId = XtAppAddWorkProc(app, spin, NULL);
  127.         spinning = GL_TRUE;
  128.         }
  129.         break;
  130.     case XK_Escape:
  131.         exit(0);
  132.     }
  133.     break;
  134.     }
  135. }
  136.  
  137. void
  138. map_state_changed(Widget w, XtPointer clientData, XEvent * event, Boolean * cont)
  139. {
  140.     switch (event->type) {
  141.     case MapNotify:
  142.     if (spinning && workId != 0) workId = XtAppAddWorkProc(app, spin, NULL);
  143.     break;
  144.     case UnmapNotify:
  145.     if (spinning) XtRemoveWorkProc(workId);
  146.     break;
  147.     }
  148. }
  149.  
  150. main(int argc, char *argv[])
  151. {
  152.     XVisualInfo    *vi;
  153.     Colormap        cmap;
  154.     GLXContext      cx;
  155.     int            saved_argc;
  156.     String       *saved_argv;
  157.  
  158.     toplevel = XtAppInitialize(&app, "Glxmotif", NULL, 0, &argc, argv,
  159.                                fallbackResources, NULL, 0);
  160.     dpy = XtDisplay(toplevel);
  161.  
  162.     /* find an OpenGL-capable RGB visual with depth buffer */
  163.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
  164.     if (vi == NULL) {
  165.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
  166.     if (vi == NULL) XtAppError(app, "no RGB visual with depth buffer");
  167.     doubleBuffer = GL_FALSE;
  168.     }
  169.     /* create an OpenGL rendering context */
  170.     cx = glXCreateContext(dpy, vi, /* no display list sharing */ None, /* favor direct */ GL_TRUE);
  171.     if (cx == NULL) XtAppError(app, "could not create rendering context");
  172.     /* create an X colormap since probably not using default visual */
  173.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
  174.  
  175.     XtVaSetValues(toplevel, XtNvisual, vi->visual, XtNdepth, vi->depth,
  176.        XtNcolormap, cmap, NULL);
  177.     XtAddEventHandler(toplevel, StructureNotifyMask, False, map_state_changed, NULL);
  178.  
  179.     form = XmCreateForm(toplevel, "form", NULL, 0);
  180.     XtManageChild(form);
  181.  
  182.     frame = XmCreateFrame(form, "frame", NULL, 0);
  183.     XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM,
  184.         XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
  185.         XmNrightAttachment, XmATTACH_FORM, NULL);
  186.     XtManageChild(frame);
  187.  
  188.     glxarea = XtCreateManagedWidget("glxarea", xmDrawingAreaWidgetClass, frame, NULL, 0);
  189.     XtAddCallback(glxarea, XmNexposeCallback, expose, NULL);
  190.     XtAddCallback(glxarea, XmNresizeCallback, resize, NULL);
  191.     XtAddCallback(glxarea, XmNinputCallback, input, NULL);
  192.  
  193.     XtRealizeWidget(toplevel);
  194.  
  195.     /* Once widget is realized (ie, associated with a created X window), we
  196.      * can bind the OpenGL rendering context to the window.
  197.      */
  198.     glXMakeCurrent(dpy, XtWindow(glxarea), cx);
  199.  
  200.     /* setup OpenGL state */
  201.     glEnable(GL_DEPTH_TEST);
  202.     glDepthFunc(GL_LEQUAL); 
  203.     glClearDepth(1.0);
  204.     glClearColor(0.0, 0.0, 0.0, 0.0);
  205.     glLoadIdentity();
  206.     gluPerspective(40.0, 1.0, 10.0, 200.0);
  207.     glTranslatef(0.0, 0.0, -50.0); glRotatef(-58.0, 0.0, 1.0, 0.0);
  208.  
  209.     XtAppMainLoop(app);
  210. }
  211.